package com.siyoumi.app.modules.app_ess.web;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.siyoumi.app.entity.*;
import com.siyoumi.app.modules.app_ess.service.*;
import com.siyoumi.app.modules.app_ess.vo.VoEssCollectFunSpan;
import com.siyoumi.app.modules.app_ess.vo.VoEssTestQuestionAnswerTotal;
import com.siyoumi.app.modules.fun.service.SvcFun;
import com.siyoumi.app.modules.user.service.SvcSysUser;
import com.siyoumi.app.service.*;
import com.siyoumi.component.XBean;
import com.siyoumi.component.http.InputData;
import com.siyoumi.controller.ApiController;
import com.siyoumi.mybatispuls.JoinWrapperPlus;
import com.siyoumi.util.XJson;
import com.siyoumi.util.XReturn;
import com.siyoumi.util.XStr;
import com.siyoumi.validator.XValidator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

//对外访问接口
@Slf4j
@RestController
@RequestMapping("/app/app_ess/api")
public class ApiAppEssOpen
        extends ApiController {
    /**
     * 评测题目列表
     */
    @GetMapping("test_question_list")
    public XReturn testQuestionList() {
        InputData inputData = InputData.fromRequest();
        String testId = inputData.input("test_id");
        XValidator.isNullOrEmpty(testId, "miss test_id");
        EssTest entityTest = SvcEssTest.getApp().getEntity(testId);
        XValidator.isNull(entityTest, "评测ID异常");

        Boolean collect = "1".equals(inputData.input("collect")); //开启统计
        String collectClassId = inputData.input("collect_class_id"); //按班级统计
        if (collect) {
            XValidator.isNullOrEmpty(collectClassId, "miss collect_class_id");
        }

        String[] select = {"etques_id",
                "etques_id",
                "etques_fun",
                "etques_question_id",
                "etques_order",
                "etqu_type",
                "etqu_question_type",
                "etqu_question",
                "etqu_question_item",
                "etqu_level",
                "etqu_answer",
                "etqu_level",
                "etqu_answer_total",
                //"etqu_answer_bingo_total",
                "etques_answer_bingo_total"
        };
        JoinWrapperPlus<EssTestQuestion> query = SvcEssTest.getBean().listQuestionQuery(inputData);
        query.join(EssQuestion.table(), EssQuestion.tableKey(), "etques_question_id");
        query.select(select);
        query.orderByAsc("etques_order").orderByDesc("etques_id");

        //IPage<EssTestQuestion> page = new Page<>(inputData.getPageIndex(), inputData.getPageSize(), false);
        //list
        List<Map<String, Object>> list = EssTestQuestionService.getBean().getMaps(query);
        //
        List<VoEssTestQuestionAnswerTotal> answerTotalList = new ArrayList<>();
        if (collect) {
            answerTotalList = SvcEssTest.getBean().getAnswerTotal(testId, List.of(collectClassId.split(",")));
        }
        //
        for (Map<String, Object> item : list) {
            EssTestQuestion entityTestQuestion = XBean.fromMap(item, EssTestQuestion.class);
            String questionItem = (String) item.get("etqu_question_item");
            List<String> questionItemArr = XJson.parseArray(questionItem, String.class);

            if (collect) { //答案统计
                VoEssTestQuestionAnswerTotal answerTotal = answerTotalList.stream()
                        .filter(i -> i.getQuestion_id().equals(entityTestQuestion.getEtques_question_id()))
                        .findFirst().orElse(null);
                if (answerTotal == null) {
                    answerTotal = VoEssTestQuestionAnswerTotal.of(entityTestQuestion.getEtques_question_id());
                }
                for (int i = 0; i < questionItemArr.size(); i++) { //数据库查不到的补0
                    if (!answerTotal.getItems().containsKey(i)) {
                        answerTotal.getItems().put(i, 0);
                    }
                }

                item.put("collect_answer", answerTotal);
            }
        }

        //难度分布
        {
            Map<Integer, List<Map<String, Object>>> levelGroup = list.stream()
                    .collect(Collectors.groupingBy(item -> (Integer) item.get("etqu_level"))); //按等级分组
            Map<Integer, Object> level = new HashMap<>();
            for (Map.Entry<Integer, List<Map<String, Object>>> item : levelGroup.entrySet()) {
                level.put(item.getKey(), item.getValue().size());
            }
            getR().setData("level_group", level);
        }

        getR().setData("list", list);
        //getR().setData("count", pageData.getTotal());
        //评测设置
        getR().setData("test", SvcEssTest.getBean().toMap(entityTest));

        return getR();
    }

    /**
     * 测评学生成绩列表
     */
    @GetMapping("test_result_list")
    public XReturn testResultList() {
        InputData inputData = InputData.fromRequest();
        String testId = inputData.input("test_id");
        XValidator.isNullOrEmpty(testId, "miss test_id");
        EssTest entityTest = SvcEssTest.getApp().getEntity(testId);
        XValidator.isNull(entityTest, "评测ID异常");
        String orderby = inputData.input("orderby", "0"); //排序
        String classId = inputData.input("class_id"); //班级ID

        String[] select = {
                "etres_id",
                "etres_submit",
                "etres_submit_date",
                "etres_submit_minute",
                "etres_test_fun",
                "user_id",
                "user_name",
                "eclass_id",
                "eclass_name",
        };
        JoinWrapperPlus<EssTestResult> query = SvcEssTest.getBean().listResultQuery(inputData);
        query.join(SysUser.table(), SysUser.tableKey()
                , "etres_uid");
        query.join(EssClassUser.table(), SysUser.tableKey(), "ecu_uid");
        query.join(EssClass.table(), EssClass.tableKey(), "ecu_class_id");
        query.select(select);
        query.eq("ecu_user_type", 0);
        switch (orderby) {
            case "0": //创建时间
                query.orderByDesc("etres_id");
                break;
            case "1": //按成绩排序
                query.orderByDesc("etres_test_fun");
                break;
        }
        if (XStr.hasAnyText(classId)) { //班级
            query.eq("etres_class_id", classId);
        }
        //list
        List<Map<String, Object>> list = EssTestResultService.getBean().getMaps(query);

        Long funMin = null; //最低分
        Long funMax = 0L; //最高分
        Long funTotal = 0L; //总得分
        //班级
        Map<String, Object> mapClass = new HashMap<>();
        for (Map<String, Object> item : list) {
            String id = (String) item.get("eclass_id");
            String name = (String) item.get("eclass_name");
            Long testFun = (Long) item.get("etres_test_fun");
            mapClass.put(id, name);

            if (funMax < testFun) {
                funMax = testFun;
            }
            if (funMin == null) {
                funMin = testFun;
            } else if (funMin > testFun) {
                funMin = testFun;
            }
            funTotal += testFun;
        }

        getR().setData("list", list);

        //得分区间显示
        //0-10 1人
        //11-20 2人
        //21-30 8人
        {
            long funSpan = entityTest.getEtest_fun_total() / 4;
            List<VoEssCollectFunSpan> listFunSpan = new ArrayList<>();
            int mathIndex = 0;
            for (Long i = 0L; i < entityTest.getEtest_fun_total(); i += funSpan) {
                Long min = i;
                long max = i + funSpan - 1;
                if (mathIndex >= 3) { //最后区间等于最大得分
                    max = entityTest.getEtest_fun_total();
                }
                long max0 = max;

                long total = list.stream().filter(item -> {
                    Long fun = (Long) item.get("etres_test_fun");
                    return fun >= min && fun <= max0;
                }).count();
                listFunSpan.add(VoEssCollectFunSpan.of(min, max, total));
                mathIndex++;
            }
            getR().put("fun_span", listFunSpan);
        }


        //评测设置
        Map<String, Object> mapTest = SvcEssTest.getBean().toMap(entityTest);
        mapTest.put("fun_max", funMax);
        mapTest.put("fun_min", funMin);
        mapTest.put("fun_total", funTotal);
        getR().setData("test", mapTest);
        //创建人
        SysUser entityTeacher = SvcSysUser.getBean().getEntity(entityTest.getEtest_uid());
        Map<String, Object> mapTeacher = XBean.toMap(entityTeacher, new String[]{"user_id", "user_name",});
        getR().setData("teacher", mapTeacher);
        //班级情况
        {
            for (Map.Entry<String, Object> item : mapClass.entrySet()) {
                //最高，最低，参与人数，总得分
                Long classFunMax = list.stream().filter(i -> i.get("eclass_id").equals(item.getKey())).map(i -> (Long) i.get("etres_test_fun")).max(Long::compareTo).get();
                Long classFunMin = list.stream().filter(i -> i.get("eclass_id").equals(item.getKey())).map(i -> (Long) i.get("etres_test_fun")).min(Long::compareTo).get();
                long classCount = list.stream().filter(i -> i.get("eclass_id").equals(item.getKey())).count();
                long classFunTotal = list.stream().filter(i -> i.get("eclass_id").equals(item.getKey())).mapToLong(i -> (Long) i.get("etres_test_fun")).sum();
                Map<String, Object> classItem = new LinkedHashMap<>();
                classItem.put("class_id", item.getKey());
                classItem.put("class_name", item.getValue());
                classItem.put("fun_max", classFunMax);
                classItem.put("fun_min", classFunMin);
                classItem.put("fun_total", classFunTotal);
                classItem.put("submit_total", classCount);

                item.setValue(classItem);
            }
            getR().setData("class", mapClass);
        }


        return getR();
    }


    /**
     * 测评学生某题目成绩明细列表
     */
    @GetMapping("test_result_item_list")
    public XReturn testResultItemList() {
        InputData inputData = InputData.fromRequest();
        String questionId = inputData.input("question_id");
        XValidator.isNullOrEmpty(questionId, "miss question_id");

        String[] select = {
                "etri_id",
                "etri_answer_state",
                "etri_create_date",
                "user_name",
                "user_username",
                "eclass_name",
        };
        JoinWrapperPlus<EssTestResultItem> query = SvcEssTest.getBean().listResultItemQuery(inputData);
        query.join(SysUser.table(), SysUser.tableKey(), "etri_uid");
        query.join(EssClass.table(), EssClass.tableKey(), "etri_class_id");
        query.select(select);
        IPage<EssTestResultItem> page = new Page<>(inputData.getPageIndex(), 5000, false);
        //list
        IPage<Map<String, Object>> pageData = EssTestResultItemService.getBean().getMaps(page, query);
        List<Map<String, Object>> list = pageData.getRecords();
        for (Map<String, Object> item : list) {
        }

        long count0 = list.stream().filter(i -> i.get("etri_answer_state").equals(0)).count();
        long count1 = list.stream().filter(i -> i.get("etri_answer_state").equals(1)).count();
        long count2 = list.stream().filter(i -> i.get("etri_answer_state").equals(2)).count();

        getR().setData("list", list);
        getR().setData("count0", count0);
        getR().setData("count1", count1);
        getR().setData("count2", count2);


        return getR();
    }

    /**
     * 评测详情
     */
    @GetMapping("test_result_info")
    public XReturn testResultInfo() {
        InputData inputData = InputData.fromRequest();
        String resultId = inputData.input("result_id");
        XValidator.isNullOrEmpty(resultId, "miss result_id");

        EssTestResult entityResult = EssTestResultService.getBean().getEntity(resultId);
        XValidator.isNull(entityResult, "result_id异常");
        //老师也能访问
        //if (!entityResult.getEtres_uid().equals(getUid())) {
        //    return EnumSys.ERR_VAL.getR("用户异常");
        //}

        inputData.put("all", "1");
        String[] select = {
                "etqu_id",
                "etqu_type",
                "etqu_module_id",
                "etqu_question_type",
                "etqu_question",
                "etqu_question_item",
                "etqu_level",
                "etqu_answer",
                "etri_test_fun",
                "etri_answer_state",
                "etri_answer",
                "emod_id",
                "emod_name",
        };
        JoinWrapperPlus<EssQuestion> query = SvcEssQuestion.getBean().listQuery(inputData);
        query.join(EssTestResultItem.table(), "etri_question_id", EssQuestion.tableKey());
        query.join(EssModule.table(), EssModule.tableKey(), "etqu_module_id");
        query.select(select);
        query.eq("etri_result_id", resultId);
        query.orderByAsc("etri_id");
        //list
        List<Map<String, Object>> list = SvcEssQuestion.getApp().getMaps(query);
        //
        //
        Map<String, Object> mapModule = new HashMap<>();
        for (Map<String, Object> item : list) {
            String moduleId = (String) item.get("emod_id");
            String moduleName = (String) item.get("emod_name");
            mapModule.put(moduleId, moduleName);
        }
        //
        for (Map<String, Object> item : list) {
            //EssQuestion entity = XBean.fromMap(item, EssQuestion.class);
            //item.put("id", entity.getKey());

            if (entityResult.getEtres_send_fun() != 1) { //未公布，不显示正确答案
                item.put("etqu_answer", null);
            }
        }

        Map<String, Object> mapResult = XBean.toMap(entityResult, new String[]{
                "etres_id",
                "etres_submit",
                "etres_submit_date",
                "etres_submit_minute",
                "etres_submit_date_end",
                "etres_end",
                "etres_test_fun",
                "etres_send_fun",
        });
        mapResult.put("left_second", entityResult.submitLeftSecond()); //考试剩余时间

        getR().setData("list", list);
        getR().setData("result", mapResult); //试卷
        //评测设置
        EssTest entityTest = SvcEssTest.getApp().getEntity(entityResult.getEtres_test_id());
        Map<String, Object> mapTest = SvcEssTest.getBean().toMap(entityTest);
        mapTest.put("date_end_left_minute", entityTest.dateEndLeftMinute());
        getR().setData("test", mapTest);
        //场景
        getR().setData("module", mapModule);
        //用户
        SysUser entityUser = SvcSysUser.getBean().getEntity(entityResult.getEtres_uid());
        Map<String, Object> mapUser = XBean.toMap(entityUser, new String[]{
                "user_id",
                "user_name",
                "user_phone",
        });
        getR().setData("user", mapUser);
        //班级
        EssClass entityClass = SvcEssClass.getApp().getEntity(entityResult.getEtres_class_id());
        Map<String, Object> mapClass = XBean.toMap(entityClass, new String[]{
                "eclass_id",
                "eclass_name",
        });
        getR().setData("class", mapClass);


        return getR();
    }


    /**
     * 评测得分情况
     */
    @GetMapping("test_info")
    public XReturn testInfo() {
        InputData inputData = InputData.fromRequest();
        String classId = inputData.input("class_id");
        XValidator.isNullOrEmpty(classId, "miss class_id");
        String studentUid = inputData.input("student_uid");

        EssClass entityClass = SvcEssClass.getApp().getEntity(classId);
        XValidator.isNull(entityClass, "班级ID异常");
        Map<String, Object> mapClass = XBean.toMap(entityClass, new String[]{
                "eclass_id",
                "eclass_name",
                "eclass_student_total",
        });
        getR().setData("class", mapClass);

        String[] select = {
                "etres_test_id",
                "COUNT(*) total",
                "SUM(etres_test_fun) fun_total",
        };
        JoinWrapperPlus<EssTestResult> query = SvcEssTest.getBean().listResultQuery(inputData);
        query.select(select);
        query.eq("etres_class_id", classId)
                .eq("etres_submit", 1)
        ;
        if (XStr.hasAnyText(studentUid)) { //指定学生
            query.eq("etres_uid", studentUid);
        }
        query.groupBy("etres_test_id");
        List<Map<String, Object>> listTotal = EssTestResultService.getBean().getMaps(query);
        if (listTotal.isEmpty()) {
            return XReturn.getR(20441, "班级无评价数据");
        }
        List<String> testIds = listTotal.stream().map(item -> (String) item.get("etres_test_id")).collect(Collectors.toList());
        List<EssTest> listTest = SvcEssTest.getApp().get(testIds);
        for (Map<String, Object> item : listTotal) {
            String testId = (String) item.get("etres_test_id");
            EssTest entityTest = listTest.stream().filter(i -> i.getEtest_id().equals(testId)).findFirst().orElse(null);

            item.put("etest_title", entityTest.getEtest_title());
            item.put("etest_fun_total", entityTest.getEtest_fun_total());
        }

        getR().setData("list", listTotal);

        return getR();
    }


    /**
     * 学生模块得分情况
     */
    @GetMapping("module_user_data")
    public XReturn moduleUserData() {
        InputData inputData = InputData.fromRequest();
        String uidStudent = inputData.input("uid_student");
        XValidator.isNullOrEmpty(uidStudent, "miss uid_student");

        EssUser entityStudent = SvcEssUser.getBean().getEntity(uidStudent);
        XValidator.isNull(entityStudent, "uid异常");

        String[] select = {
                "emod_name",
                "emod_id",
                "emuser_uid",
                "emuser_test1_count",
                "emuser_test1_fun",
                "emuser_module_count",
                "emuser_module_fun",
                "emuser_file_count",
                "emuser_file_fun",
        };
        JoinWrapperPlus<EssModule> query = SvcEssModule.getBean().listQuery();
        query.leftJoin(EssModuleUser.table(), EssModule.tableKey(), "emuser_module_id", "AND emuser_uid = {0}", uidStudent);
        query.select(select);
        List<Map<String, Object>> list = SvcEssModule.getApp().getMaps(query);
        for (Map<String, Object> item : list) {
            item.put("exist", item.containsKey("emuser_test1_count"));
        }

        getR().setData("list", list);

        Map<String, Object> mapUser = XBean.toMap(entityStudent, new String[]{
                "euser_id",
                "euser_module_count",
                "euser_module_fun",
                "euser_file_count",
                "euser_file_fun",
                "euser_test0_count",
                "euser_test0_fun",
                "euser_test1_count",
                "euser_test1_fun",
        });
        mapUser.put("fun", SvcFun.getBean().getFun(uidStudent));
        getR().setData("user", mapUser);

        //所属班级
        {
            List<Map<String, Object>> listClass = SvcEssClass.getBean().getList(uidStudent);
            getR().put("list_class", listClass);
        }

        return getR();
    }
}
